package com.ogawa.projectcommon.activity


import android.content.Intent
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.alibaba.android.arouter.launcher.ARouter
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ToastUtils
import com.jeremyliao.liveeventbus.LiveEventBus
import com.ogawa.base.R
import com.ogawa.base.base.BaseActivity
import com.ogawa.base.bean.DeviceStateChangeBean
import com.ogawa.base.bean.LoadState
import com.ogawa.base.bean.MqttAccountBean
import com.ogawa.base.constants.Constants
import com.ogawa.projectcommon.constants.UrlPathConstant
import com.ogawa.base.mqtt.*
import com.ogawa.base.utils.SpUtil
import com.ogawa.base.utils.SpUtil.Companion.SN
import com.ogawa.base.utils.isEmptyStr
import com.ogawa.base.utils.printNoNull
import com.ogawa.projectcommon.constants.IntentKeyConstant.LIVE_EVENT_BUS_KEY_DEVICE_STATE_CHANGE
import com.ogawa.projectcommon.constants.IntentKeyConstant.LIVE_EVENT_BUS_KEY_MSG_CALL_BACK
import com.ogawa.projectcommon.viewmodel.GetMqttAccountViewModel
import org.eclipse.paho.client.mqttv3.MqttMessage

abstract class BaseMqttActivity : BaseActivity()/*, MqttSendMsgCallback,
    MqttConnectListener,
    MqttDeviceStateListener,*/, MqttConnectListener, MqttReceiveListener {

    /*
     *  处理主题的订阅以及椅子模型的初始化
     */
    abstract fun abstractOnConnectStateChange(isConnect: Boolean)

    /*
     *  处理接收到MQTT的消息
     */
    abstract fun abstractonReceiveMqttMsg(opic: String, message: MqttMessage)

    private lateinit var mGetMqttAccountViewModel: GetMqttAccountViewModel


    override fun initView() {
        super.initView()
        initViewModel()


        LiveEventBus.get(LIVE_EVENT_BUS_KEY_DEVICE_STATE_CHANGE, DeviceStateChangeBean::class.java)
            .observe(this, Observer {
                onDeviceStateChange()
            })

        LiveEventBus.get(LIVE_EVENT_BUS_KEY_MSG_CALL_BACK, Int::class.java).observe(this, Observer {
            sendMsgCallback(it)
        })

//        MqttManager.getInstance().registerMqttDeviceStateListener(this)
//        MqttManager.getInstance().registerMqttSendMsgCallback(this)


        val isNeedReConnect = SpUtil.get(SpUtil.IS_NEED_RE_CONNECT_MQTT, true) as Boolean
        val curSn = SpUtil.get(SN, "") as String
        var isNeedGetPwd = true
        for (item in MqttManager.getInstance().mqttAccountBeanList){
            if (!isEmptyStr(item.sn) && item.sn.equals(curSn)){
                isNeedGetPwd = false
                MqttManager.getInstance().setMqttMsg(item.username,item.password)
            }
        }

        if (isNeedReConnect) {
            SpUtil.set(SpUtil.IS_NEED_RE_CONNECT_MQTT, false)
            if (isNeedGetPwd) {
                LogUtils.e("获取账号")
                getMqttAccount()
            } else {
                LogUtils.e("直接连接")
                connectMqtt()
            }
        }


    }

    override fun onResume() {
        super.onResume()
        MqttManager.getInstance().registeronReceiveMqttMsg(this)
        MqttManager.getInstance().setMqttConnectListener(this)
    }

    override fun onStop() {
        super.onStop()
        MqttManager.getInstance().clearMqttConnectListener()
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        getMqttAccount()
    }

    override fun onDestroy() {
        super.onDestroy()
        mHandler.removeCallbacksAndMessages(null)
        MqttManager.getInstance().unRegisteronReceiveMqttMsg(this)
//        MqttManager.getInstance().unRegisterMqttDeviceStateListener(this)
//        MqttManager.getInstance().unRegisterMqttSendMsgCallback(this)
    }

    private fun initViewModel() {
        mGetMqttAccountViewModel =
            ViewModelProviders.of(this).get(GetMqttAccountViewModel::class.java)
        mGetMqttAccountViewModel.let(lifecycle::addObserver)
        mGetMqttAccountViewModel.loadState.observe(this, Observer {
            when (it) {
                is LoadState.Loading -> {
                    showLoadingDialog(canceledOnTouchOutside = false)
                }
                is LoadState.Fail -> {
                    dismissLoadingDialog()
                }
                is LoadState.Success -> {
                    dismissLoadingDialog()
                }
            }
        })

        mGetMqttAccountViewModel.mqttAccountBean.observe(this, Observer {
            val curSn = SpUtil.get(SN, "") as String
            var bean = MqttAccountBean()
            bean.sn = curSn
            bean.username = it?.username.toString()
            bean.password = it?.password.toString()
            MqttManager.getInstance().addMqttAccountBean(bean)

            MqttManager.getInstance().setMqttMsg(it?.username.toString(), it?.password.toString())
            connectMqtt()
        })
    }

    /**
     * 获取Mqtt账号密码
     */
    private fun getMqttAccount() {
        if (!MqttManager.getInstance().isConnect) {
            LogUtils.e(TAG, "获取Mqtt账号密码 getMqttAccount")
            mGetMqttAccountViewModel.getMqttAccount()
        }
    }


    /**
     * 连接Mqtt
     */

    private fun connectMqtt() {
        LogUtils.e(TAG, "connectMqtt")
        if (MqttManager.getInstance().isConnect) {
            MqttManager.getInstance().disconnect()
        }
        mHandler.postDelayed({
            if (MqttManager.getInstance().connect()) {
                lateShowLoading(getString(R.string.waiting), canceledOnTouchOutside = false)
                mHandler.postDelayed({
                    dismissLoadingDialog()
                    ToastUtils.showShort(
                        getString(R.string.mqtt_connect_time_out)
                    )
                    MqttManager.getInstance().disconnect()
                }, 30 * 1000)
            }
        }, 500)
    }

    open fun publish(func: String?, model: String, addition: String?) {
        if (MqttManager.getInstance().isConnect) { //已连接
            lateShowLoading(getString(R.string.waiting), canceledOnTouchOutside = false)
            MqttManager.getInstance().publish(func, model, addition)
        } else { //未连接
            connectMqtt()
        }
    }

    open fun publish(func: String?, model: String) {
        publish(func, model, null)
    }

    override fun onConnectStateChange(isConnect: Boolean) {
        abstractOnConnectStateChange(isConnect)
//        mHandler.removeCallbacksAndMessages(null)
//        if (isConnect) {
//            dismissLoadingDialog()
//            val sn: String = SpUtil.get(SpUtil.SN, "") as String
//            val instance = MqttManager.getInstance()
//            instance.subscribe(
//                arrayOf(
//                    "cmd/up/$sn",
//                    "cmd/back/$sn/${instance.clientId}"
//                ), intArrayOf(2, 2), object : IMqttActionListener {
//                    override fun onSuccess(asyncActionToken: IMqttToken) {
//                        publish(Constants.RUNNING_STATUS_QUERY, "")
//                    }
//                    override fun onFailure(
//                        asyncActionToken: IMqttToken,
//                        exception: Throwable
//                    ) {
//                        LogUtils.e("onFailure: "  + (exception?.message))
//                    }
//                })
//        } else {
//            Massage3209EArmchair.getInstance().runningStatus = 0
//            Massage3209EArmchair.getInstance().deviceStatusBean = null
//            onDeviceStateChange()
//        }
    }

    private fun sendMsgCallback(state: Int) {
        dismissLoadingDialog()
        when (state) {
            MqttSendMsgCallback.FAIL -> ToastUtils.showShort(
                getString(R.string.send_command_fail)
            )
            MqttSendMsgCallback.TIMEOUT -> ToastUtils.showShort(
                getString(R.string.send_command_timeout)
            )
            MqttSendMsgCallback.OFFLINE -> ToastUtils.showShort(
                getString(R.string.device_offline)
            )
        }
    }

    override fun onReceiveMqttMsg(topic: String, message: MqttMessage) {
        abstractonReceiveMqttMsg(topic, message)
//        LogUtils.e("$TAG 处理消息")
//        val msg = String(message.payload)
//        if (topic.contains("up")) { //设备状态的消息
//            if (!msg.contains("fault") && !msg.contains("elecTime") && !msg.contains("heartbeat")) {
//                val deviceStatusBean: Device3209EStateBean = GsonUtils.fromJson(
//                    msg,
//                    Device3209EStateBean::class.java
//                )
//                val runningStatus = deviceStatusBean.functions.runningStatus
//                if (runningStatus != null) {
//                    val state = runningStatus.modelValue.toInt()
//                    Massage3209EArmchair.getInstance().setRunningStatus(state)
//                    if (state == 0) {
//                        Massage3209EArmchair.getInstance().setDeviceStatusBean(null)
//                    }
//                }
//                val resetSucccessFlag = deviceStatusBean.functions.resetSucccessFlag
//                if (resetSucccessFlag != null) { //复位标志即为关机信号
//                    Massage3209EArmchair.getInstance().setRunningStatus(0)
//                    Massage3209EArmchair.getInstance()
//                        .setReset(resetSucccessFlag.modelValue.toInt())
//                    //                    DeviceOffBean deviceOffBean = mGson.fromJson(msg, DeviceOffBean.class);
//                    Massage3209EArmchair.getInstance().setDeviceStatusBean(null)
//                    //                    MassageArmchair.getInstance().setDeviceOffBean(deviceOffBean);
//                }
//                if (deviceStatusBean.functions.autoProgram != null) {
//                    Massage3209EArmchair.getInstance().setDeviceStatusBean(deviceStatusBean)
//                    Massage3209EArmchair.getInstance().setDeviceOffBean(null)
//                }
//            } else if (msg.contains("fault")) { //设备故障码
//                val functions: String = JSONObject(msg).getString("functions")
//                val fault = JSONObject(functions).getString("fault")
//                val faultResult = JSONObject(fault).getString("modelValue")
//                Massage3209EArmchair.getInstance().setFault(faultResult)
//            }
////            for (mDeviceStateListener in mDeviceStateListeners) {
////                mDeviceStateListener.onDeviceStateChange()
////            }
////            onDeviceStateChange()
//            LiveEventBus.get(KEY_DEVICE_STATE_CHANGE, DeviceStateChangeBean::class.java).post(DeviceStateChangeBean())
//        } else if (topic.contains("back")) { //发送消息的回复
//            val cmdResult: String = JSONObject(msg).getString("cmdResult")
//            var sendState = 0
//            when (cmdResult) {
//                "success" -> sendState = MqttSendMsgCallback.SUCCESS
//                "fail" -> sendState = MqttSendMsgCallback.FAIL
//                "timeout" -> sendState = MqttSendMsgCallback.TIMEOUT
//                "offline" -> sendState = MqttSendMsgCallback.OFFLINE
//            }
////            for (mMsgSendCallback in mMsgSendCallbacks) {
////                mMsgSendCallback.sendMsgCallback(sendState)
////            }
////            sendMsgCallback(sendState)
//            LiveEventBus.get(KEY_MSG_CALL_BACK, Int::class.java).post(sendState)
//        }

    }


    fun isSnExist(): Boolean {
//        val sn = SpUtil.get(SpUtil.SN, "") as String
//        if (sn.isEmpty()) {
//            ARouter.getInstance()
//                .build(UrlPathConstant.ACTIVITY_DISTRIBUTIONNETWORK_START_CONNECT)
//                .navigation()
//            return false
//        }
        return true
    }

    open fun onDeviceStateChange() {

    }


}